#include "ChatServiceImpl.hpp"
#include "CSession.hpp"
#include "Defer.hpp"
#include "MysqlMgr.hpp"
#include "RedisMgr.hpp"
#include "UserMgr.hpp"
#include "const.hpp"
#include "data.hpp"
#include <grpcpp/support/status.h>
#include <json/value.h>
#include <memory>
ChatServiceImpl::ChatServiceImpl() {}

Status ChatServiceImpl::NotifyAddFriend(::grpc::ServerContext *context,
                                        const ::message::AddFriendReq *request,
                                        ::message::AddFriendRsp *response) {

  std::cout << "applyUid is " << request->applyuid() << ", toUid is "
            << request->touid() << ",desc is " << request->desc() << ".\n";
  // 收到添加好友申请
  // 查找用户是否在本服务器
  int touid = request->touid();
  auto session = UserMgr::GetInstance().GetSession(touid);
  Defer defer([request, response]() {
    response->set_error(ErrorCodes::Success);
    response->set_applyuid(request->applyuid());
    response->set_touid(request->touid());
  });

  // 用户不在线
  if (session == nullptr) {
    return Status::OK;
  }
  // 用户在线 发送通知
  Json::Value rtvalue;
  rtvalue["error"] = ErrorCodes::Success;
  rtvalue["applyuid"] = request->applyuid();
  rtvalue["name"] = request->name();
  rtvalue["desc"] = request->desc();

  std::string return_str = rtvalue.toStyledString();
  // 向客户端发送请求
  session->Send(return_str.c_str(), return_str.length(),
                ID_NOTIFY_ADD_FRIEND_REQ);

  return Status::OK;
}
Status ChatServiceImpl::RplyAddFriend(::grpc::ServerContext *context,
                                      const ::message::ReplyfriendReq *request,
                                      ::message::ReplyFriendRsp *response) {
  return Status::OK;
}
Status ChatServiceImpl::SendChatMsg(::grpc::ServerContext *context,
                                    const ::message::SendChatMsgReq *request,
                                    ::message::SendChatMsgRsp *response) {
  return Status::OK;
}

Status
ChatServiceImpl::NotifyAuthFriend(::grpc::ServerContext *context,
                                  const ::message::AuthFriendReq *request,
                                  ::message::AuthFriendRsp *response) {
  int fromuid = request->fromuid();
  int touid = request->touid();
  auto session = UserMgr::GetInstance().GetSession(touid);
  if (!session) {
    // 用户不在线
    return Status::OK;
  }
  // 获取发送认证请求的用户信息
  auto userInfo = std::make_shared<UserInfo>();
  std::string base_key = USER_BASE_INFO + std::to_string(fromuid);
  bool is_ok = GetBaseInfo(base_key, fromuid, userInfo);
  if (!is_ok) {
    std::cout << "NotifyAuthFriend: Error in obtaining authentication request "
                 "sender information!\n";
    return Status::OK;
  }
  Json::Value root;
  root["error"] = ErrorCodes::Success;
  root["name"] = userInfo->name;
  root["uid"] = userInfo->uid;
  root["email"] = userInfo->email;
  // 用户备注 从用户端获取 或应用启动时加载
  std::string rt_str = root.toStyledString();
  session->Send(rt_str.c_str(), rt_str.length(), ID_NOTIFY_AUTH_FRIEND_REQ);
  return Status::OK;
}

Status
ChatServiceImpl::NotifyTextChatMsg(::grpc::ServerContext *context,
                                   const ::message::TextChatMsgReq *request,
                                   ::message::TextChatMsgRsp *response) {
  response->set_error(ErrorCodes::Success);
  std::string msg_id = request->msgid();
  std::string message = request->msgcontent();
  std::string send_time = request->send_time();
  int fromuid = request->fromuid();
  int touid = request->touid();
  // 获取接收消息者的session
  auto session = UserMgr::GetInstance().GetSession(touid);
  // 用户下线
  if (session == nullptr) {
    return Status::OK;
  }
  // 用户在线 发送数据
  Json::Value root;
  root["fromuid"] = fromuid;
  root["message"] = message;
  root["send_time"] = send_time;
  root["msg_id"] = msg_id;
  root["touid"] = touid;
  // 发送消息
  std::string rt_str = root.toStyledString();
  session->Send(rt_str.c_str(), rt_str.length(), ID_TEXT_CHAT_MSG_REQ);
  return Status::OK;
}

bool ChatServiceImpl::GetBaseInfo(std::string &base_key, int uid,
                                  std::shared_ptr<UserInfo> &userInfo) {
  // 从Redis中查询用户信息
  std::string info_str = "";
  bool success = RedisMgr::GetInstance().Get(base_key, info_str);
  if (success) {
    Json::Reader reader;
    Json::Value root;
    reader.parse(info_str, root);
    userInfo->uid = root["uid"].asInt();
    userInfo->name = root["name"].asString();
    userInfo->pwd = root["pwd"].asString();
    userInfo->email = root["email"].asString();
  } else {
    // redis中没有数据，从mysql中查询
    std::shared_ptr<UserInfo> user_info = nullptr;
    user_info = MysqlMgr::GetInstance().GetUser(uid);
    if (user_info == nullptr) {
      return false;
    }
    userInfo = user_info;
    // 将数据写入Redis中
    Json::Value redis_root;
    redis_root["uid"] = userInfo->uid;
    redis_root["name"] = userInfo->name;
    redis_root["pwd"] = userInfo->pwd;
    redis_root["email"] = userInfo->email;
    std::string root_str = redis_root.toStyledString();
    RedisMgr::GetInstance().Set(base_key, root_str);
  }
  return true;
}